#include<stdio.h>
#include<Mesh_IO/Mesh_IO.h>

#include<Mesh/libcell_iterator.h>

#include<Mesh/Mesh_Operator.h>
#include<tool/libcell_tools_view.h>

#include<libcell_macros.h>
#include<Viewer_Interpreter/Viewer_OpenGL_Interpreter.h>
#include<tool/viewer_tools.h>

void adjust_mesh(Mesh*);


#define Matrix4x4 Viewer_Matrix4x4_
typedef struct SCreen_Shot_Anima{
    int mark;
    float screenshot_area[4];
    char* out_obj_path;
    Viewer_World* vw;
}SCreen_Shot_Anima;

void screen_shot_anima_init(SCreen_Shot_Anima* scsa)
{
    scsa->mark=0;
    scsa->out_obj_path=NULL;
    scsa->screenshot_area[0]=0;scsa->screenshot_area[1]=0;scsa->screenshot_area[2]=0;scsa->screenshot_area[3]=0;
    scsa->vw=NULL;
}

void viewer_screen_shot_anima(Viewer_Intera*vi)
{
    SCreen_Shot_Anima*scsa=(SCreen_Shot_Anima*)(vi->representation); 
    if(scsa->mark==1)
    {
        return ;
    }
    Interactor_GlobalInfo* g_info=vi->g_info;
    g_info->screenshot_area[0]=scsa->screenshot_area[0];g_info->screenshot_area[1]=scsa->screenshot_area[1];
    g_info->screenshot_area[2]=scsa->screenshot_area[2];g_info->screenshot_area[3]=scsa->screenshot_area[3];
    //printf("%lf %lf %lf %lf\n",g_info->screenshot_area[0],g_info->screenshot_area[1],g_info->screenshot_area[2],g_info->screenshot_area[3]);
 
    if(g_info->screenshot_image!=NULL)
    {
        printf("hrere\n");
        float proportion_x=((float)g_info->resolution[0])/(float)(1280);float proportion_y=((float)g_info->resolution[1])/(float)(720);
        int minx=1920*g_info->screenshot_area[0],miny=1080*g_info->screenshot_area[1];
        int maxx=1920*g_info->screenshot_area[2],maxy=1080*g_info->screenshot_area[3];
        int width=maxx-minx,height=maxy-miny;
        if(minx>=0&&miny>=0&&width>0&&height>0)
        {
            ImageInfo imi;
            imi.data=g_info->screenshot_image;imi.width=width;imi.height=height;imi.n=3;
            _is_reverse_image_writing(1);
            //printf("width :%d %d\n",width,height);
           // printf("ererere\n");

            _Write_BMP_File_(scsa->out_obj_path,&imi);
            g_info->screenshot_area[0]=0;g_info->screenshot_area[1]=0;g_info->screenshot_area[2]=0;g_info->screenshot_area[3]=0;
            if(scsa->vw!=NULL)
            {
                scsa->vw->should_close=1; 
            } 

             
            scsa->mark=1;
        }
    }
}


void test(char* obj_path,char* out_obj_path)
{
    Viewer_World_Manager vwm;
    viewer_world_manager_init(&vwm);

    Viewer_World *vw=vwm.create_world(&vwm,NULL);

//*****************************************


//*****************************************
    Node* n=vw->create_something(vw,"Camera");
    Viewer_Something*vs=(Viewer_Something*)(n->value);
    Viewer_Camera* vc=(Viewer_Camera*)(vs->evolution);
    vc->is_using=1;
    // Matrix4x4 *p=Projection(M_PI/3.0f,
    //     (float)(vw->g_info->resolution[0])/(float)(vw->g_info->resolution[1]),0.5f,200.0f);
    // p->copy_data(vc->Proj,p);
    vc->Proj->identity(vc->Proj);
    vc->matrix->identity(vc->matrix);
    vc->matrix_inverse->identity(vc->matrix_inverse);

    // Matrix4x4_free(p);
    free_node(n); 
//*******************************************
    Mesh mesh;
    Mesh_init(&mesh);
    _ReadObj_(&mesh,obj_path);
    //_ReadCell_(&mesh,"cube.cell");
    //_ReadOff_(&mesh,"bunny.off",3);

    adjust_mesh(&mesh);
     

    n=vw->create_something(vw,"Faces");
    vs=(Viewer_Something*)(n->value);
    Viewer_Faces*vf =(Viewer_Faces*)(vs->evolution);
    // vf->Data_rows=3;
    // vf->Data_index_rows=1;
    // viewer_tools_fill_data("%f",vf->Data_rows*3,&(vf->Data),
    //     0.0,0.0,0.0,
    //     0.5,0.0,0.0,
    //     0.0,0.5,0.0);
    // viewer_tools_fill_data("%u",vf->Data_index_rows*4,&(vf->Data_index),
    //     3,0,1,2);

     
    vf->Data_rows=mesh.num_v(&mesh);
    vf->Data_index_rows=mesh.num_c(&mesh);  

    get_data_from_2dim_cell(&mesh,&(vf->Data),&(vf->Data_index));
    //vf->normal_rows=vf->Data_index_rows; 
    vf->color_rows=vf->Data_index_rows;
    vf->set_color(vf,1.0,0.0,0.0,1.0);

    free_node(n);

    Mesh_free(&mesh);
//*******************************************
    //***********
    // n=vw->create_something(vw,"Intera");
    // vs=(Viewer_Something*)(n->value);
    // Viewer_Intera*vi=(Viewer_Intera*)(vs->evolution);
    // Viewer_Arcroll*va=(Viewer_Arcroll*)malloc(sizeof(Viewer_Arcroll));
    // viewer_arcroll_init(va);
    // va->mc=vc;
    // va->vw=vw;
    // vi->representation=(void*)va;
    // vi->cursor_position_callback=viewer_Arcroll_cursor_position_callback;
    // vi->scroll_callback=viewer_Arcroll_scroll_callback;
    // vi->mouse_button_callback=viewer_Arcroll_mouse_button_callback;
    // vi->key_callback=viewer_Arcroll_key_callback; 

    // free_node(n);

    n=vw->create_something(vw,"Texts");
    vs=(Viewer_Something*)(n->value);
    Viewer_Texts* vtexts=(Viewer_Texts*)(vs->evolution);
    vtexts->str=(wchar_t*)malloc(sizeof(wchar_t)*80);
    memset(vtexts->str,0,sizeof(wchar_t)*80);
    wcscpy(vtexts->str,L"nihaodsgdooasuytwmqniz");

    int len=wcslen(vtexts->str);
    vtexts->text_alpha=(float*)malloc(sizeof(float)*len);
    memset(vtexts->text_alpha,0,sizeof(float)*len);
    vtexts->xy[0]=-1.0;vtexts->xy[1]=0.95;vtexts->scale=0.9;

    free_node(n);
    //
   
    //
    n=vw->create_something(vw,"Intera");
    vs=(Viewer_Something*)(n->value);
    Viewer_Intera*vi=(Viewer_Intera*)(vs->evolution);
    SCreen_Shot_Anima* scsa=(SCreen_Shot_Anima*)malloc(sizeof(SCreen_Shot_Anima));
    screen_shot_anima_init(scsa); 
    scsa->screenshot_area[0]=0;scsa->screenshot_area[1]=0;
    scsa->screenshot_area[2]=1.0;scsa->screenshot_area[3]=1.0;
    scsa->vw=vw;
    scsa->out_obj_path=out_obj_path;

    vi->representation=(void*)scsa;

    vi->animation=viewer_screen_shot_anima;
    
    free_node(n);




    //vw->should_close=1;

//******************************************
    Viewer_Opengl_Interpreter voi;
    viewer_opengl_interpreter_initn(&voi,&vwm);
    voi.interpreter(&voi);
    viewer_opengl_interpreter_free(&voi);
    viewer_world_manager_free(&vwm);  

}

void adjust_mesh(Mesh* m)
{
    double mins[3]={0},maxs[3]={0};
    auto vit=m->v_begin(m);
    if(vit==m->v_end(m))
    {
        return;
    }
    mins[0]=quote(vit)->point[0];mins[1]=quote(vit)->point[1];mins[2]=quote(vit)->point[2];
    maxs[0]=quote(vit)->point[0];maxs[1]=quote(vit)->point[1];maxs[2]=quote(vit)->point[2];
    for(;vit!=m->v_end(m);vit++)
    {
        for(int i=0;i<3;i++)
        {
            quote(vit)->point[i]>maxs[i]?(maxs[i]=quote(vit)->point[i]):(maxs[i]=maxs[i]);
            quote(vit)->point[i]<mins[i]?(mins[i]=quote(vit)->point[i]):(mins[i]=mins[i]);
        }
    }

    (*m)-mins;

    double max_axi=maxs[0]-mins[0];
    (maxs[1]-mins[1]>max_axi)?(max_axi=maxs[1]-mins[1]):(max_axi=max_axi);
    //(maxs[2]-mins[2]>max_axi)?(max_axi=maxs[2]-mins[2]):(max_axi=max_axi);

    (*m)*(2.0/max_axi);
    double weiyi[3]={-1.0,-1.0,0.0};
    (*m)+weiyi; 
    vit=m->v_begin(m);
    for(;vit!=m->v_end(m);vit++)
    {
        quote(vit)->point[2]*= 0.9/(maxs[2]-mins[2]);
    }
    (*m)*0.9;

}

int main()
{
    test("./bim_seperate/A2/bim_seperate/1#/1#楼-建筑.obj","./bim_seperate/A2/bim_seperate/1#/1#.bmp");
    
    printf("end\n");
    char str1[10]={NULL},str2[10]={NULL};
    

    printf("end\n");
    return 0;
}
